﻿namespace Resonator.Domain.Models
{
	using System;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Globalization;
	using System.Text;
	using Castle.ActiveRecord;
	using NHibernate.Search.Attributes;
	using Field = NHibernate.Search.Attributes.FieldAttribute;

	[Serializable]
	[ActiveRecord]
	[Indexed]
	[DebuggerDisplay("Name={Name} Phrase={Phrase} LanguageName={LanguageName} Context={Context} Translations={Translations.Count}")]
	public class Resource : LocalizableModel
	{
		private string _name = string.Empty;
		private string _phrase = string.Empty;
		private string _context = string.Empty;
		private IList<Translation> _translations = new List<Translation>();

		[Property(NotNull = true)]
		[Field(Index.Tokenized, Store=Store.No)]
		public virtual string Name
		{
			get { return _name; }
			set { _name = value ?? string.Empty; }
		}

		[Property(NotNull=true)]
		[Field(Index.Tokenized, Store = Store.No)]
		public virtual string Phrase
		{
			get { return _phrase; }
			set { _phrase = value ?? string.Empty; }
		}

		[Property(NotNull=true)]
		[Field(Index.Tokenized, Store = Store.No)]
		public virtual string Context
		{
			get { return _context; }
			set { _context = value ?? string.Empty; }
		}

		protected override void GetFullText(StringBuilder builder)
		{
			builder.Append( Name );
			builder.Append( ' ' );
			builder.Append( Phrase );
			builder.Append( ' ' );
			builder.Append( Context );
			builder.Append( ' ' );

			base.GetFullText( builder );

			foreach( Translation translation in Translations )
			{
				builder.Append( ' ' );
				builder.Append( translation.FullText );
			}
		}

		[HasMany(Cascade=ManyRelationCascadeEnum.All, Inverse=true)]
		[IndexedEmbedded]
		public virtual IList<Translation> Translations
		{
			get { return _translations; }
			set { _translations = value ?? new List<Translation>(); }
		}

		public virtual Translation FindTranslation(CultureInfo culture)
		{
			foreach( Translation translation in Translations )
			{
				if( translation.Culture.Equals( culture ) )
				{
					return translation;
				}
			}

			return null;
		}

		public virtual void AddTranslation(Translation translation)
		{
			if( translation == null )
			{
				throw new ArgumentNullException( "translation" );
			}

			translation.Resource = this;
			Translations.Add( translation );
		}

		public virtual void CopyFrom(Resource resource)
		{
			if( resource == null )
			{
				throw new ArgumentNullException( "resource" );
			}

			Name = resource.Name;
			Phrase = resource.Phrase;
			Context = resource.Context;
		}

		public virtual void CopyTranslations(Resource resource)
		{
			foreach( Translation translation in resource.Translations )
			{
				AddTranslation( Translation.Copy( translation ) );
			}
		}

		public static Resource Create(string phrase)
		{
			return Create( phrase, string.Empty );
		}

		public static Resource Create(string phrase, string name)
		{
			return Create( phrase, name, string.Empty ); 
		}

		public static Resource Create(string phrase, string name, string context)
		{
			Resource resource = new Resource();
			resource.Phrase = phrase;
			resource.Name = name;
			resource.Context = context;
			return resource;
		}

		public virtual Resource AddTranslation(string cultureName, string phrase)
		{
			Translation translation = new Translation();
			translation.Culture = new CultureInfo( cultureName );
			translation.Phrase = phrase;
			AddTranslation( translation );
			return this;
		}
	}
}